

<!DOCTYPE html>
<html class="writer-html5" lang="en" >
<head>
  <meta charset="utf-8" />
  
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  
  <title>Basic Workflow &mdash; Ceph Documentation</title>
  

  
  <link rel="stylesheet" href="../../../_static/ceph.css" type="text/css" />
  <link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
  <link rel="stylesheet" href="../../../_static/graphviz.css" type="text/css" />
  <link rel="stylesheet" href="../../../_static/css/custom.css" type="text/css" />

  
  
    <link rel="shortcut icon" href="../../../_static/favicon.ico"/>
  

  
  

  

  
  <!--[if lt IE 9]>
    <script src="../../../_static/js/html5shiv.min.js"></script>
  <![endif]-->
  
    
      <script type="text/javascript" id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
        <script src="../../../_static/jquery.js"></script>
        <script src="../../../_static/underscore.js"></script>
        <script src="../../../_static/doctools.js"></script>
    
    <script type="text/javascript" src="../../../_static/js/theme.js"></script>

    
    <link rel="index" title="Index" href="../../../genindex/" />
    <link rel="search" title="Search" href="../../../search/" />
    <link rel="next" title="测试 - 单元测试" href="../tests-unit-tests/" />
    <link rel="prev" title="问题跟踪" href="../issue-tracker/" /> 
</head>

<body class="wy-body-for-nav">

   
  <header class="top-bar">
    

















<div role="navigation" aria-label="breadcrumbs navigation">

  <ul class="wy-breadcrumbs">
    
      <li><a href="../../../" class="icon icon-home"></a> &raquo;</li>
        
          <li><a href="../">向 Ceph 贡献：开发者指南</a> &raquo;</li>
        
      <li>Basic Workflow</li>
    
    
      <li class="wy-breadcrumbs-aside">
        
          
            <a href="../../../_sources/dev/developer_guide/basic-workflow.rst.txt" rel="nofollow"> View page source</a>
          
        
      </li>
    
  </ul>

  
  <hr/>
</div>
  </header>
  <div class="wy-grid-for-nav">
    
    <nav data-toggle="wy-nav-shift" class="wy-nav-side">
      <div class="wy-side-scroll">
        <div class="wy-side-nav-search"  style="background: #eee" >
          

          
            <a href="../../../">
          

          
            
            <img src="../../../_static/logo.png" class="logo" alt="Logo"/>
          
          </a>

          

          
<div role="search">
  <form id="rtd-search-form" class="wy-form" action="../../../search/" method="get">
    <input type="text" name="q" placeholder="Search docs" />
    <input type="hidden" name="check_keywords" value="yes" />
    <input type="hidden" name="area" value="default" />
  </form>
</div>

          
        </div>

        
        <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
          
            
            
              
            
            
              <ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../../../start/intro/">Ceph 简介</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../install/">安装 Ceph</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../cephadm/">Cephadm</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../rados/">Ceph 存储集群</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../cephfs/">Ceph 文件系统</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../rbd/">Ceph 块设备</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../radosgw/">Ceph 对象网关</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../mgr/">Ceph 管理器守护进程</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../mgr/dashboard/">Ceph 仪表盘</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../api/">API 文档</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../architecture/">体系结构</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="../">开发者指南</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="../intro/">简介</a></li>
<li class="toctree-l2"><a class="reference internal" href="../essentials/">必备知识</a></li>
<li class="toctree-l2"><a class="reference internal" href="../merging/">何时、合并了什么</a></li>
<li class="toctree-l2"><a class="reference internal" href="../issue-tracker/">问题追踪器</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#">基本工作流</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#updating-the-tracker">Updating the tracker</a></li>
<li class="toctree-l3"><a class="reference internal" href="#forking-and-cloning-the-ceph-repository">Forking and Cloning the Ceph Repository</a><ul>
<li class="toctree-l4"><a class="reference internal" href="#forking-the-ceph-repository">Forking The Ceph Repository</a></li>
<li class="toctree-l4"><a class="reference internal" href="#cloning-your-fork">Cloning Your Fork</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="#configuring-your-local-environment">Configuring Your Local Environment</a><ul>
<li class="toctree-l4"><a class="reference internal" href="#resetting-local-master-to-upstream-master">Resetting Local Master to Upstream Master</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="#creating-a-bugfix-branch">Creating a Bugfix branch</a></li>
<li class="toctree-l3"><a class="reference internal" href="#fixing-the-bug-locally">Fixing the bug locally</a></li>
<li class="toctree-l3"><a class="reference internal" href="#opening-a-github-pull-request">Opening a GitHub pull request</a></li>
<li class="toctree-l3"><a class="reference internal" href="#understanding-automated-pr-validation">Understanding Automated PR validation</a><ul>
<li class="toctree-l4"><a class="reference internal" href="#notes-on-pr-make-check-test">Notes on PR make check test</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="#integration-tests-aka-ceph-qa-suite">Integration tests AKA ceph-qa-suite</a></li>
<li class="toctree-l3"><a class="reference internal" href="#code-review">Code review</a></li>
<li class="toctree-l3"><a class="reference internal" href="#amending-your-pr">Amending your PR</a></li>
<li class="toctree-l3"><a class="reference internal" href="#merging">Merging</a><ul>
<li class="toctree-l4"><a class="reference internal" href="#proper-merge-commit-format">Proper Merge Commit Format</a></li>
<li class="toctree-l4"><a class="reference internal" href="#using-githubmap-to-find-a-reviewer-s-email-address">Using .githubmap to Find a Reviewer’s Email Address</a></li>
<li class="toctree-l4"><a class="reference internal" href="#using-git-log-to-find-a-reviewer-s-email-address">Using “git log” to find a Reviewer’s Email Address</a></li>
<li class="toctree-l4"><a class="reference internal" href="#using-ptl-tool-to-generate-merge-commits">Using ptl-tool to Generate Merge Commits</a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../tests-unit-tests/">测试：单元测试</a></li>
<li class="toctree-l2"><a class="reference internal" href="../testing_integration_tests/">测试：集成测试(Teuthology)</a></li>
<li class="toctree-l2"><a class="reference internal" href="../running-tests-locally/">测试：在本地运行测试</a></li>
<li class="toctree-l2"><a class="reference internal" href="../dash-devel/">Ceph Dashboard 开发者文档 (之前是 HACKING.rst)</a></li>
<li class="toctree-l2"><a class="reference internal" href="../jaegertracing/">Tracing 开发者文档</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../cephadm/">Cephadm 开发者文档</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../internals/">Ceph 内幕</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../governance/">项目管理</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../foundation/">Ceph 基金会</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../ceph-volume/">ceph-volume</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../releases/general/">Ceph 版本（总目录）</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../releases/">Ceph 版本（索引）</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../security/">Security</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../glossary/">Ceph 术语</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../jaegertracing/">Tracing</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../translation_cn/">中文版翻译资源</a></li>
</ul>

            
          
        </div>
        
      </div>
    </nav>

    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">

      
      <nav class="wy-nav-top" aria-label="top navigation">
        
          <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
          <a href="../../../">Ceph</a>
        
      </nav>


      <div class="wy-nav-content">
        
        <div class="rst-content">
        
          <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
           <div itemprop="articleBody">
            
<div id="dev-warning" class="admonition note">
  <p class="first admonition-title">Notice</p>
  <p class="last">This document is for a development version of Ceph.</p>
</div>
  <div id="docubetter" align="right" style="padding: 5px; font-weight: bold;">
    <a href="https://pad.ceph.com/p/Report_Documentation_Bugs">Report a Documentation Bug</a>
  </div>

  
  <div class="section" id="basic-workflow">
<h1>Basic Workflow<a class="headerlink" href="#basic-workflow" title="Permalink to this headline">¶</a></h1>
<p>The following chart illustrates the basic Ceph development workflow:</p>
<p>This page assumes that you are a new contributor with an idea for a bugfix or
enhancement, but do not know how to proceed. Watch the <a class="reference external" href="https://www.youtube.com/watch?v=t5UIehZ1oLs">Getting Started with
Ceph Development</a> video for a
practical summary of this workflow.</p>
<div class="section" id="updating-the-tracker">
<h2>Updating the tracker<a class="headerlink" href="#updating-the-tracker" title="Permalink to this headline">¶</a></h2>
<p>Before you start, you should know the <a class="reference internal" href="../issue-tracker/#issue-tracker"><span class="std std-ref">问题跟踪</span></a> (Redmine) number
of the bug you intend to fix. If there is no tracker issue, now is the time to
create one for code changes.  Straightforward documentation cleanup does
not necessarily require a corresponding tracker issue. However, an issue
(ticket) should be created if one is adding new documentation chapters or
files, or for other substantial changes.</p>
<p>The tracker ticket serves to explain the issue (bug) to your fellow Ceph
developers and keep them informed as you make progress toward resolution.  To
this end, please provide a descriptive title and write appropriate information
and details into the description.  When composing the ticket’s title, consider “If I
want to search for this ticket two years from now, what keywords will I search
for?”</p>
<p>If you have sufficient tracker permissions, assign the bug to yourself by
setting the <code class="docutils literal notranslate"><span class="pre">Assignee</span></code> field.  If your tracker permissions have not been
elevated, simply add a comment with a short message like “I am working on this
issue”.</p>
</div>
<div class="section" id="forking-and-cloning-the-ceph-repository">
<h2>Forking and Cloning the Ceph Repository<a class="headerlink" href="#forking-and-cloning-the-ceph-repository" title="Permalink to this headline">¶</a></h2>
<p>This section, and the ones that follow, correspond to nodes in the above chart.</p>
<p>The upstream code is found at <a class="reference external" href="https://github.com/ceph/ceph.git">https://github.com/ceph/ceph.git</a>, which is known
as the “upstream repo”, or simply “upstream”. As the chart shows, we will make
a local copy of this repository, modify it, test our modifications, then submit
the modifications for review and merging.</p>
<p>A local copy of the upstream code is made by</p>
<ol class="arabic simple">
<li><p>Forking the upstream repo on GitHub, and</p></li>
<li><p>Cloning your fork to make a local working copy</p></li>
</ol>
<div class="section" id="forking-the-ceph-repository">
<h3>Forking The Ceph Repository<a class="headerlink" href="#forking-the-ceph-repository" title="Permalink to this headline">¶</a></h3>
<p>See the <a class="reference external" href="https://help.github.com/articles/fork-a-repo/#platform-linux">GitHub documentation</a> for
detailed instructions on forking. In short, if your GitHub username is
“mygithubaccount”, your fork of the upstream repo will appear at
<code class="docutils literal notranslate"><span class="pre">https://github.com/mygithubaccount/ceph</span></code>.</p>
</div>
<div class="section" id="cloning-your-fork">
<h3>Cloning Your Fork<a class="headerlink" href="#cloning-your-fork" title="Permalink to this headline">¶</a></h3>
<p>Once you have created your fork, clone it by running:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><style type="text/css">
span.prompt1:before {
  content: "$ ";
}
</style><span class="prompt1">git clone https://github.com/mygithubaccount/ceph</span>
</pre></div></div><p>You must fork the Ceph repository before you clone it.  Without forking, you cannot
open a <a class="reference external" href="https://docs.github.com/en/free-pro-team&#64;latest/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request">GitHub pull request</a>.</p>
<p>For more information on using GitHub, refer to <a class="reference external" href="https://help.github.com/">GitHub Help</a>.</p>
</div>
</div>
<div class="section" id="configuring-your-local-environment">
<h2>Configuring Your Local Environment<a class="headerlink" href="#configuring-your-local-environment" title="Permalink to this headline">¶</a></h2>
<p>In the local environment created in the previous step, you now have a copy of
the <code class="docutils literal notranslate"><span class="pre">master</span></code> branch in <code class="docutils literal notranslate"><span class="pre">remotes/origin/master</span></code>. This fork
(<a class="reference external" href="https://github.com/mygithubaccount/ceph.git">https://github.com/mygithubaccount/ceph.git</a>) is frozen in time and the
upstream repo (<a class="reference external" href="https://github.com/ceph/ceph.git">https://github.com/ceph/ceph.git</a>, typically abbreviated to
<code class="docutils literal notranslate"><span class="pre">ceph/ceph.git</span></code>) is updated frequently by other contributors. This means that
you must sync your fork periodically. Failure to synchronize your fork may
result in your commits and pull requests failing to merge because they refer to
file contents that have changed since you last synchronized your fork.</p>
<p>Configure your local git environment with your name and email address.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span class="prompt1">git config user.name <span class="s2">&quot;FIRST_NAME LAST_NAME&quot;</span></span>
<span class="prompt1">git config user.email <span class="s2">&quot;MY_NAME@example.com&quot;</span></span>
</pre></div></div><p>Add the upstream repo as a “remote” and fetch it:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span class="prompt1">git remote add ceph https://github.com/ceph/ceph.git</span>
<span class="prompt1">git fetch ceph</span>
</pre></div></div><p>These commands fetch all the branches and commits from <code class="docutils literal notranslate"><span class="pre">ceph/ceph.git</span></code> to the
local git repo as <code class="docutils literal notranslate"><span class="pre">remotes/ceph/$BRANCH_NAME</span></code> and can be referenced as
<code class="docutils literal notranslate"><span class="pre">ceph/$BRANCH_NAME</span></code> in local git commands.</p>
<div class="section" id="resetting-local-master-to-upstream-master">
<h3>Resetting Local Master to Upstream Master<a class="headerlink" href="#resetting-local-master-to-upstream-master" title="Permalink to this headline">¶</a></h3>
<p>Your local <code class="docutils literal notranslate"><span class="pre">master</span></code> branch can be reset to the upstream Ceph <code class="docutils literal notranslate"><span class="pre">master</span></code>
branch by running the following commands:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span class="prompt1">git fetch ceph</span>
<span class="prompt1">git checkout master</span>
<span class="prompt1">git reset --hard ceph/master</span>
<span class="prompt1">git push -u origin master</span>
</pre></div></div><p>This procedure should be followed often, in order to keep your local <code class="docutils literal notranslate"><span class="pre">master</span></code>
in sync with upstream <code class="docutils literal notranslate"><span class="pre">master</span></code>.</p>
</div>
</div>
<div class="section" id="creating-a-bugfix-branch">
<h2>Creating a Bugfix branch<a class="headerlink" href="#creating-a-bugfix-branch" title="Permalink to this headline">¶</a></h2>
<p>Create a branch for your bugfix:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span class="prompt1">git checkout master</span>
<span class="prompt1">git checkout -b fix_1</span>
<span class="prompt1">git push -u origin fix_1</span>
</pre></div></div><p>This creates a local branch called <code class="docutils literal notranslate"><span class="pre">fix_1</span></code> in our GitHub fork. At this point,
the <code class="docutils literal notranslate"><span class="pre">fix_1</span></code> branch is identical to the <code class="docutils literal notranslate"><span class="pre">master</span></code> branch, but not for long!
You are now ready to modify the code.  Be careful to always run <cite>git checkout
master</cite> first, otherwise you may find commits from an unrelated branch mixed
with your new work.</p>
</div>
<div class="section" id="fixing-the-bug-locally">
<h2>Fixing the bug locally<a class="headerlink" href="#fixing-the-bug-locally" title="Permalink to this headline">¶</a></h2>
<p>In the <a class="reference external" href="https://tracker.ceph.com">Ceph issue tracker</a>, change the status of
the tracker issue to “In progress”.  This communicates to other Ceph
contributors that you have begun working on a fix, which helps to avoid
duplication of effort.  If you don’t have permission to change that field, your
previous comment that you are working on the issue is sufficient.</p>
<p>Your fix may be very simple and require only minimal testing. But that’s not
likely. It is more likely that the process of fixing your bug will be iterative
and will involve trial and error, as well as skill. An explanation of how to
fix bugs is beyond the scope of this document. Instead, we focus on the
mechanics of the process in the context of the Ceph project.</p>
<p>For a detailed discussion of the tools available for validating bugfixes,
see the chapters on testing.</p>
<p>For now, let us assume that you have finished work on the bugfix, that you have
tested the bugfix , and that you believe that it works. Commit the changes to
your local branch using the <code class="docutils literal notranslate"><span class="pre">--signoff</span></code> option (here represented as the <cite>s</cite>
portion of the <cite>-as</cite> flag):</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span class="prompt1">git commit -as</span>
</pre></div></div><p>Push the changes to your fork:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span class="prompt1">git push origin fix_1</span>
</pre></div></div></div>
<div class="section" id="opening-a-github-pull-request">
<h2>Opening a GitHub pull request<a class="headerlink" href="#opening-a-github-pull-request" title="Permalink to this headline">¶</a></h2>
<p>The next step is to open a GitHub pull request (PR). This makes your bugfix
visible to the community of Ceph contributors.  They will review it and may
perform additional testing and / or request changes.</p>
<p>This is the point where you “go public” with your modifications.  Be prepared
to receive suggestions and constructive criticism in the form of comments
within the PR. Don’t worry!  The Ceph project is a friendly place!</p>
<p>If you are uncertain how to create and manage pull requests, you may read
<a class="reference external" href="https://help.github.com/articles/using-pull-requests/">this GitHub pull request tutorial</a>.</p>
<p>For ideas on what constitutes a “good” pull request, see
the <a class="reference external" href="https://wiki.openstack.org/wiki/GitCommitMessages">Git Commit Good Practice</a> article at the <a class="reference external" href="https://wiki.openstack.org/wiki/Main_Page">OpenStack Project Wiki</a>.</p>
<p>and our own <a class="reference external" href="https://github.com/ceph/ceph/blob/master/SubmittingPatches.rst">Submitting Patches</a> document.</p>
<p>Once your pull request (PR) is opened, update the <a class="reference internal" href="../issue-tracker/#issue-tracker"><span class="std std-ref">问题跟踪</span></a> by
adding a comment directing other contributors to your PR. The comment can be
as simple as:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>*PR*: https://github.com/ceph/ceph/pull/$NUMBER_OF_YOUR_PULL_REQUEST
</pre></div>
</div>
</div>
<div class="section" id="understanding-automated-pr-validation">
<h2>Understanding Automated PR validation<a class="headerlink" href="#understanding-automated-pr-validation" title="Permalink to this headline">¶</a></h2>
<p>When you create or update your PR, the Ceph project’s <a class="reference external" href="https://en.wikipedia.org/wiki/Continuous_integration">Continuous Integration
(CI)</a> infrastructure
automatically tests it. At the time of this writing (September 2020), the
automated CI testing included five tests:</p>
<ol class="arabic simple">
<li><p>a test to check that the commits are properly signed (see <a class="reference internal" href="../essentials/#submitting-patches"><span class="std std-ref">补丁的提交</span></a>):</p></li>
<li><p>a test to check that the documentation builds</p></li>
<li><p>a test to check that the submodules are unmodified</p></li>
<li><p>a test to check that the API is in order</p></li>
<li><p>a <a class="reference internal" href="../tests-unit-tests/#make-check"><span class="std std-ref">make check</span></a> test</p></li>
</ol>
<p>Additional tests may be performed depending on which files your PR modifies.</p>
<p>The <a class="reference internal" href="../tests-unit-tests/#make-check"><span class="std std-ref">make check</span></a> test builds the PR and runs it through a battery of
tests. These tests run on servers operated by the Ceph Continuous
Integration (CI) team. When the tests complete, the result will be shown
on GitHub in the pull request itself.</p>
<p>You should test your modifications before you open a PR.
Refer to the chapters on testing for details.</p>
<div class="section" id="notes-on-pr-make-check-test">
<h3>Notes on PR make check test<a class="headerlink" href="#notes-on-pr-make-check-test" title="Permalink to this headline">¶</a></h3>
<p>The GitHub <a class="reference internal" href="../tests-unit-tests/#make-check"><span class="std std-ref">make check</span></a> test is driven by a Jenkins instance.</p>
<p>Jenkins merges your PR branch into the latest version of the base branch before
starting tests. This means that you don’t have to rebase the PR to pick up any fixes.</p>
<p>You can trigger PR tests at any time by adding a comment to the PR - the
comment should contain the string “test this please”. Since a human subscribed
to the PR might interpret that as a request for him or her to test the PR, we
recommend that you address Jenkins directly. For example, write “jenkins retest
this please”.  For efficiency a single re-test can also be requested with
e.g. “jenkins test signed”.  For reference, a list of these requests is
automatically added to the end of each new PR’s description.</p>
<p>If there is a build failure and you aren’t sure what caused it, check the
<a class="reference internal" href="../tests-unit-tests/#make-check"><span class="std std-ref">make check</span></a> log. To access it, click on the “details” (next
to the <a class="reference internal" href="../tests-unit-tests/#make-check"><span class="std std-ref">make check</span></a> test in the PR) link to enter the Jenkins web
GUI. Then click on “Console Output” (on the left).</p>
<p>Jenkins is configured to search logs for strings known to have been associated
with <a class="reference internal" href="../tests-unit-tests/#make-check"><span class="std std-ref">make check</span></a> failures in the past. However, there is no
guarantee that these known strings are associated with any given
<a class="reference internal" href="../tests-unit-tests/#make-check"><span class="std std-ref">make check</span></a> failure. You’ll have to read through the log to determine the
cause of your specific failure.</p>
</div>
</div>
<div class="section" id="integration-tests-aka-ceph-qa-suite">
<h2>Integration tests AKA ceph-qa-suite<a class="headerlink" href="#integration-tests-aka-ceph-qa-suite" title="Permalink to this headline">¶</a></h2>
<p>Since Ceph is complex, it may be necessary to test your fix to
see how it behaves on real clusters running on physical or virtual
hardware. Tests designed for this purpose live in the <a class="reference external" href="https://github.com/ceph/ceph/tree/master/qa/">ceph/qa
sub-directory</a> and are run via the <a class="reference external" href="https://github.com/ceph/teuthology">teuthology framework</a>.</p>
<p>The Ceph community has access to the <a class="reference external" href="https://wiki.sepia.ceph.com/doku.php">Sepia lab</a> where <a class="reference external" href="../testing_integration_tests/tests-integration-testing-teuthology-intro">integration tests</a> can be run
on physical hardware.
Other developers may add tags like “needs-qa” to your PR.  This allows PRs that
need testing to be merged into a single branch and tested all at the same time.
Since teuthology suites can take hours (even days in some cases) to run, this
can save a lot of time.</p>
<p>To request access to the Sepia lab, start <a class="reference external" href="https://wiki.sepia.ceph.com/doku.php?id=vpnaccess">here</a>.</p>
<p>Integration testing is discussed in more detail in the <a class="reference external" href="../testing_integration_tests/tests-integration-testing-teuthology-intro">integration
tests</a> chapter.</p>
</div>
<div class="section" id="code-review">
<h2>Code review<a class="headerlink" href="#code-review" title="Permalink to this headline">¶</a></h2>
<p>Once your bugfix has been thoroughly tested, or even during this process,
it will be subjected to code review by other developers. This typically
takes the form of comments in the PR itself, but can be supplemented
by discussions on <a class="reference internal" href="../essentials/#irc"><span class="std std-ref">IRC</span></a> and the <a class="reference internal" href="../essentials/#mailing-list"><span class="std std-ref">邮件列表</span></a>.</p>
</div>
<div class="section" id="amending-your-pr">
<h2>Amending your PR<a class="headerlink" href="#amending-your-pr" title="Permalink to this headline">¶</a></h2>
<p>While your PR is going through testing and <a class="reference internal" href="#code-review">Code Review</a>, you can
modify it at any time by editing files in your local branch.</p>
<p>After updates are committed locally (to the <code class="docutils literal notranslate"><span class="pre">fix_1</span></code> branch in our
example), they need to be pushed to GitHub so they appear in the PR.</p>
<p>Modifying the PR is done by adding commits to the <code class="docutils literal notranslate"><span class="pre">fix_1</span></code> branch upon
which it is based, often followed by rebasing to modify the branch’s git
history. See <a class="reference external" href="https://www.atlassian.com/git/tutorials/rewriting-history">this tutorial</a> for a good
introduction to rebasing. When you are done with your modifications, you
will need to force push your branch with:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span class="prompt1">git push --force origin fix_1</span>
</pre></div></div><p>Why do we take these extra steps instead of simply adding additional commits
the the PR?  It is best practice for a PR to consist of a single commit; this
makes for clean history, eases peer review of your changes, and facilitates
merges.  In rare circumstances it also makes it easier to cleanly revert
changes.</p>
</div>
<div class="section" id="merging">
<h2>Merging<a class="headerlink" href="#merging" title="Permalink to this headline">¶</a></h2>
<p>The bugfix process completes when a project lead merges your PR.</p>
<p>When this happens, it is a signal for you (or the lead who merged the PR)
to change the <a class="reference internal" href="../issue-tracker/#issue-tracker"><span class="std std-ref">问题跟踪</span></a> status to “Resolved”. Some issues may be
flagged for backporting, in which case the status should be changed to
“Pending Backport” (see the <a class="reference internal" href="../essentials/#backporting"><span class="std std-ref">补丁移植（ Backporting ）</span></a> chapter for details).</p>
<p>See also <a class="reference internal" href="../merging/#merging"><span class="std std-ref">合并提交：范围和节奏</span></a> for more information on merging.</p>
<div class="section" id="proper-merge-commit-format">
<h3>Proper Merge Commit Format<a class="headerlink" href="#proper-merge-commit-format" title="Permalink to this headline">¶</a></h3>
<p>This is the most basic form of a merge commit:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">doc</span><span class="o">/</span><span class="n">component</span><span class="p">:</span> <span class="n">title</span> <span class="n">of</span> <span class="n">the</span> <span class="n">commit</span>

<span class="n">Reviewed</span><span class="o">-</span><span class="n">by</span><span class="p">:</span> <span class="n">Reviewer</span> <span class="n">Name</span> <span class="o">&lt;</span><span class="n">rname</span><span class="nd">@example</span><span class="o">.</span><span class="n">com</span><span class="o">&gt;</span>
</pre></div>
</div>
<p>This consists of two parts:</p>
<ol class="arabic simple">
<li><p>The title of the commit / PR to be merged.</p></li>
<li><p>The name and email address of the reviewer. Enclose the reviewer’s email
address in angle brackets.</p></li>
</ol>
</div>
<div class="section" id="using-githubmap-to-find-a-reviewer-s-email-address">
<h3>Using .githubmap to Find a Reviewer’s Email Address<a class="headerlink" href="#using-githubmap-to-find-a-reviewer-s-email-address" title="Permalink to this headline">¶</a></h3>
<p>If you cannot find the email address of the reviewer on his or her GitHub
page, you can look it up in the <strong>.githubmap</strong> file, which can be found in
the repository at <strong>/ceph/.githubmap</strong>.</p>
</div>
<div class="section" id="using-git-log-to-find-a-reviewer-s-email-address">
<h3>Using “git log” to find a Reviewer’s Email Address<a class="headerlink" href="#using-git-log-to-find-a-reviewer-s-email-address" title="Permalink to this headline">¶</a></h3>
<p>If you cannot find a reviewer’s email address by using the above methods, you
can search the git log for their email address. Reviewers are likely to have
committed something before.  If they have made previous contributions, the git
log will probably contain their email address.</p>
<p>Use the following command</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><style type="text/css">
span.prompt2:before {
  content: "[branch-under-review]$ ";
}
</style><span class="prompt2">git log</span>
</pre></div></div></div>
<div class="section" id="using-ptl-tool-to-generate-merge-commits">
<h3>Using ptl-tool to Generate Merge Commits<a class="headerlink" href="#using-ptl-tool-to-generate-merge-commits" title="Permalink to this headline">¶</a></h3>
<p>Another method of generating merge commits involves using Patrick Donnelly’s
<strong>ptl-tool</strong> pull commits. This tool can be found at
<strong>/ceph/src/script/ptl-tool.py</strong>.  Merge commits that have been generated by
the <strong>ptl-tool</strong> have the following form:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Merge</span> <span class="n">PR</span> <span class="c1">#36257 into master</span>
<span class="o">*</span> <span class="n">refs</span><span class="o">/</span><span class="n">pull</span><span class="o">/</span><span class="mi">36257</span><span class="o">/</span><span class="n">head</span><span class="p">:</span>
        <span class="n">client</span><span class="p">:</span> <span class="n">move</span> <span class="n">client_lock</span> <span class="n">to</span> <span class="n">_unmount</span><span class="p">()</span>
        <span class="n">client</span><span class="p">:</span> <span class="n">add</span> <span class="n">timer_lock</span> <span class="n">support</span>
<span class="n">Reviewed</span><span class="o">-</span><span class="n">by</span><span class="p">:</span> <span class="n">Patrick</span> <span class="n">Donnelly</span> <span class="o">&lt;</span><span class="n">pdonnell</span><span class="nd">@redhat</span><span class="o">.</span><span class="n">com</span><span class="o">&gt;</span>
</pre></div>
</div>
</div>
</div>
</div>



           </div>
           
          </div>
          <footer>
    <div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
        <a href="../tests-unit-tests/" class="btn btn-neutral float-right" title="测试 - 单元测试" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
        <a href="../issue-tracker/" class="btn btn-neutral float-left" title="问题跟踪" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
    </div>

  <hr/>

  <div role="contentinfo">
    <p>
        &#169; Copyright 2016, Ceph authors and contributors. Licensed under Creative Commons Attribution Share Alike 3.0 (CC-BY-SA-3.0).

    </p>
  </div> 

</footer>
        </div>
      </div>

    </section>

  </div>
  

  <script type="text/javascript">
      jQuery(function () {
          SphinxRtdTheme.Navigation.enable(true);
      });
  </script>

  
  
    
   

</body>
</html>